Skip to content

Conversation

delkopiso
Copy link

Summary

Fixes issue where Convex CLI always creates .env.local files even when required environment variables (CONVEX_DEPLOYMENT, CONVEX_URL, etc.) are already available in the shell environment. This was problematic for users who manage secrets with external tools, use direnv, or deploy in CI/CD environments.

This PR contains two commits that together resolve the issue:

  1. Skip .env.local creation when environment variables exist - Modified the core logic to check process.env before creating .env.local files
  2. Fix misleading log messages - Updated logging to only show file creation messages when files are actually written to disk

Problem Solved

Root Cause: The CLI only checked for environment variables in files (.env.local, .env) but not in the shell environment (process.env).

Before:

  • CLI always created .env.local even when CONVEX_DEPLOYMENT was set via direnv, CI/CD, or shell exports
  • Users saw misleading "Saved deployment details to .env.local" messages even when no file was needed
  • Problematic for users who avoid leaving environment settings in local filesystem

After:

  • CLI detects existing environment variables in process.env and skips file creation
  • Users only see file creation messages when files are actually written
  • Respects users' preferred environment management workflows

Fixes #191

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

@Copilot Copilot AI review requested due to automatic review settings August 20, 2025 03:03
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR improves the Convex CLI's environment variable handling by checking process.env before creating .env.local files, preventing unnecessary file creation when environment variables are already available in the shell environment.

Key changes include:

  • Enhanced writeConvexUrlToEnvFile to check process.env for existing environment variables before file creation
  • Updated writeDeploymentEnvVar to skip file operations when CONVEX_DEPLOYMENT is already set in the environment
  • Added comprehensive test coverage for the new behavior

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
npm-packages/convex/src/cli/lib/envvars.ts Added process.env check to skip .env.local creation when variables exist
npm-packages/convex/src/cli/lib/deployment.ts Added early return when CONVEX_DEPLOYMENT exists in process.env
npm-packages/convex/src/cli/lib/envvars.test.ts New test file covering process.env behavior scenarios
npm-packages/convex/src/cli/lib/deployment.test.ts Added test for deployment env var skip behavior

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

@delkopiso
Copy link
Author

@nipunn1313 could you take at look at this PR for me? I'd appreciate any feedback

@thomasballinger
Copy link
Contributor

@delkopiso these values aren't secret, and they're needed by the frontend to know where to connect to. What's your use case, what's the flow you'd like to support here?

@thomasballinger
Copy link
Contributor

I'll wait to hear what you're trying to support, if I were guessing I'd say

  • check out CONVEX_DEPLOY_KEY
  • are you creating apps that dont' have a frontend, or deploy the frontend seprately? If so, what would help you here?
  • is this for self-hosted cases where the deployment name and URL are constant, and you don't want to enable creating new local dev deployments? If so, say more about that

@delkopiso
Copy link
Author

@thomasballinger my primary usecase is working on separate projects concurrently. I first ran into issues because the access token setup assumes a single account for all projects. Ultimately, there are two things I want to solve for:

  • Not having to manage variables (secret or not) in more than one way. My projects aren't using .env files.
  • Being able to context switch across projects without need to redo the cli auth flow.

I documented in #191 that setting CONVEX_DEPLOY_KEY didn't prevent the dev flow from trying to write the files.

@thomasballinger
Copy link
Contributor

Hm, re multiple accounts that's just not something we're anticipating; can you add your single account to multiple teams instead? It sounds like you want to be logged into multiple accounts and have which account is used depend on the project; nothing like this planned but if there's a good reason you need multiple accounts it sounds like that's something to think about for the future.

Re the first bullet

Not having to manage variables (secret or not) in more than one way. My projects aren't using .env files.

Every time someone checks your project repo out and runs convex, they get a new CONVEX_URL. It sounds like you want to take this environment variable and move it to another system. You have another way of telling the frontend/client/website what URL to use to talk to the backend.

Are you saying that if the correct environment variables exist in process.env (and they match what the CLI would have generated) then they shouldn't be written? We could add an option for that. I don't want to silently not write .env.local just because the environment variables are present, because the more important thing is that the website have them available.

I totally agree re CONVEX_DEPLOYMENT, that shouldn't be in .env.local; that's just a convenient place to put it to remember which project a repo checkout is associated with.

Two potential alternative proposals here:

  1. How about a dev option for not writing the client environment variable at all? This is the CONVEX_URL / VITE_CONVEX_URL etc. one.
  2. For CONVEX_DEPLOYMENT, it would be nice if CONVEX_DEPLOY_KEY or --env-file also caused this not to be written. It sounds like you want another option, which is if CONVEX_DEPLOYMENT is set (and as long as that's a valid) it won't be written. That part sounds good.

@delkopiso
Copy link
Author

@thomasballinger that's correct on all counts. For CONVEX_DEPLOYMENT, CONVEX_DEPLOY_KEY not writing the file would suffice too.

@suiramdev
Copy link

I also need it because I have configured convex in a “packages/convex” directory inside my turbo repository, where all applications and packages depend on a single “.env” file at the root using “dotenv-run.”

@thomasballinger
Copy link
Contributor

@suiramdev do you not use any .env.local files, or similar file that is not committed to the repo?

Each time you change dev deployments, (in the future, you might use different deployments for different branches) we need to update the NEXT_PUBLIC_CONVEX_URL / VITE_CONVEX_URL / CONVEX_URL so the frontend knows where to find that deployment. Where would you want this to be written to? This url should be in version control.

@delkopiso Similar question: where should this be written?

We can eventually move away from CONVEX_DEPLOYMENT by moving it to a new hidden file that should be git-ignored like .convex/config.json. But whenever the deployment URL changes you need to know what url to use to find it.

@suiramdev
Copy link

suiramdev commented Aug 28, 2025

My intention in responding to this PR was to 'bump' it. Let me explain why I am interested in it more clearly @thomasballinger. Despite a small example showcasing its use with Turborepo, Convex appears to have been designed to attach to one front end rather than multiple ones via a monorepository. In the context of my boilerplate, I would like to use Convex as a shared package in the @packages/convex directory, which is powered by Turborepo. For the sake of ease of setup, I have chosen to maintain one and only one .env file at the root of this monorepository.

However, I am unable to specify an environment file or use the one provided through process.env, as I use dotenv-run to spread that root .env file across my packages and apps.
This results in the creation of a .env.local file in the @packages/convex directory each time pnpx convex dev is run, and requires the user to interact with the CLI interface to choose their convex environment.

In my opinion, interaction with the CLI should be optional. It should be similar to what some CLI tools do with the option -i.
Convex should use the environment variable whenever it already exists.

Am I missing something that convex is trying to solve in this generated .env.local file, which in our case conflicts with owns? Shouldn't the environment variables defined by convex with pnpx convex env set be located in a very specific convex folder, as you said .convex/?

Let me know if you'd like more information, or if I'm missing out some details.


I discovered that convex exposes a --env-file option on pnpx convex dev but it does not appear to be documented and does not work in the same way we intend here : A user also questioned about it

@thomasballinger
Copy link
Contributor

@suiramdev I see you have a .env at the root, is that .env version controlled? If not, great, let's make convex dev write CONVEX_URL and CONVEX_DEPLOYMENT there. If so, would you also want a .env.local there too?

Am I missing something that convex is trying to solve in this generated .env.local file

It sounds like you get it, but to reiterate, whenever convex dev runs it needs to set the CONVEX_URL / VITE_CONVEX_URL / NEXT_PUBLIC_CONVEX_URL to the url of the (possibly newly created) deployment. This can absolutely be moved to a different .env file!

@thomasballinger
Copy link
Contributor

Shouldn't the environment variables defined by convex with pnpx convex env set be located in a very specific convex folder, as you said .convex/?

This is pretty different, convex env set is for setting environment variables in the deployment. The environment variables we're talking about here are not in the deployment, they're for use in the applications that need to connect to the deployment.

@thomasballinger
Copy link
Contributor

In my opinion, interaction with the CLI should be optional.

Absolutely, this is important. The only guaranteed way to make convex dev non-interactive today is to 1) use a CONVEX_DEPLOY_KEY (this is the suggested way to do build pipelines in e.g. Vercel) or 2) have a configured CONVEX_DEPLOYMENT, or 3) run npx convex dev --configure with a bunch of additional flags like --team and --project.

@thomasballinger
Copy link
Contributor

However, I am unable to specify an environment file or use the one provided through process.env, as I use dotenv-run to spread that root .env file across my packages and apps.

Agree --env-file is not fully implemented yet, it should allow you to save CONVEX_DEPLOYMENT and CONVEX_URL / VITE_CONVEX_URL / NEXT_PUBLIC_CONVEX_URL to a different file.

use the one provided through process.env

What do you mean by this?

@thomasballinger
Copy link
Contributor

Would love to hear more, so far I'm hearing

  1. Let's provide a way to specify a different file than .env.local (e.g. ../../.env) to write CONVEX_URL to
  2. (lower priority) provide to disable writing to this file, instead crashing if CONVEX_URL doesn't match
  3. (lower priority) write CONVEX_DEPLOYMENT to a different place

let me know how these differ from your expectations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Convex CLI always creates .env.local even when environment variables are already set
3 participants